package com.example.controller;

import cn.hutool.core.lang.Dict;
import com.example.common.Result;
import com.example.entity.Account;
import com.example.entity.DiskFiles;
import com.example.service.DiskFilesService;
import com.github.pagehelper.PageInfo;
import lombok.val;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 磁盘文件管理控制器（前端操作接口）
 * 提供文件上传/下载/预览、目录管理、分页查询等核心功能
 */
@RestController
@RequestMapping("/diskFiles")
public class DiskFilesController {

    @Resource
    private DiskFilesService diskFilesService;

    /**
     * 新增文件/文件夹
     * @param file 上传的文件对象（文件夹上传时可为空）
     * @param name 文件/文件夹名称
     * @param folder 是否为文件夹标识（true-文件夹/false-文件）
     * @param folderId 所属父目录ID（根目录传null）
     * @param request HTTP请求上下文（用于获取用户会话）
     * @return {@link Result} 操作结果对象
     */
    @PostMapping("/add")
    public Result add(MultipartFile file, String name, String folder, Integer folderId, HttpServletRequest request) {
        diskFilesService.add(file, name, folder, folderId, request);
        return Result.success();
    }

    /**
     * 文件下载接口
     * @param flag 文件唯一标识符（数据库存储的文件标识）
     * @param response HTTP响应对象（用于输出文件流）
     * @implNote 直接通过response输出流返回文件内容，不返回JSON数据
     */
    @GetMapping("/download/{flag}")
    public void download(@PathVariable String flag, HttpServletResponse response) {
        diskFilesService.download(flag, response);
    }

    /**
     * 文件在线预览
     * @param id 文件记录ID
     * @param response HTTP响应对象（用于输出预览内容）
     * @implNote 支持文档/图片等常见格式的在线预览，通过响应流返回处理后的内容
     */
    @GetMapping("/preview/{id}")
    public void preview(@PathVariable Integer id, HttpServletResponse response) {
        diskFilesService.preview(id, response);
    }

    /**
     * 删除单个文件/文件夹
     * @param id 要删除的文件记录ID
     * @return {@link Result} 操作结果对象
     * @implNote 物理删除或逻辑删除取决于业务配置（当前实现为逻辑删除）
     */
    @DeleteMapping("/delete/{id}")
    public Result deleteById(@PathVariable Integer id) {
        diskFilesService.deleteById(id);
        return Result.success();
    }

    /**
     * 批量删除文件/文件夹
     * @param ids 要删除的文件记录ID列表
     * @return {@link Result} 操作结果对象
     */
    @DeleteMapping("/delete/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        diskFilesService.deleteBatch(ids);
        return Result.success();
    }

    /**
     * 更新文件/文件夹信息
     * @param diskFiles 包含更新信息的文件对象（至少包含id字段）
     * @return {@link Result} 操作结果对象
     */
    @PutMapping("/update")
    public Result updateById(@RequestBody DiskFiles diskFiles) {
        diskFilesService.updateById(diskFiles);
        return Result.success();
    }

    /**
     * 根据ID查询文件详情
     * @param id 文件记录ID
     * @return {@link Result} 包含文件详细信息的结果对象
     */
    @GetMapping("/selectById/{id}")
    public Result selectById(@PathVariable Integer id) {
        DiskFiles diskFiles = diskFilesService.selectById(id);
        return Result.success(diskFiles);
    }

    /**
     * 查询所有文件记录（支持条件过滤）
     * @param diskFiles 查询条件对象（支持按名称/类型等属性过滤）
     * @param request HTTP请求上下文（用于权限校验）
     * @return {@link Result} 包含文件列表的结果对象
     */
    @GetMapping("/selectAll")
    public Result selectAll(DiskFiles diskFiles, HttpServletRequest request) {
        List<DiskFiles> list = diskFilesService.selectAll(diskFiles, request);
        return Result.success(list);
    }

    /**
     * 分页查询文件记录
     * @param diskFiles 查询条件对象
     * @param pageNum 当前页码（默认1）
     * @param pageSize 每页显示数量（默认10）
     * @return {@link Result} 包含分页数据的结果对象（PageInfo封装分页信息）
     */
    @GetMapping("/selectPage")
    public Result selectPage(DiskFiles diskFiles,
                             @RequestParam(defaultValue = "1") Integer pageNum,
                             @RequestParam(defaultValue = "10") Integer pageSize) {
        PageInfo<DiskFiles> page = diskFilesService.selectPage(diskFiles, pageNum, pageSize);
        return Result.success(page);
    }

    /**
     * 查询目录层级路径
     * @param folderId 目录ID（从叶子节点开始查询）
     * @return {@link Result} 包含目录层级列表的结果对象（按从根到叶子的顺序排列）
     * @implNote 使用递归查询构建目录路径，最终结果反转顺序展示
     */
    @GetMapping("/selectFolders")
    public Result selectFolders(Integer folderId) {
        List<DiskFiles> list = new ArrayList<>();
        if (folderId == null) return Result.success(list);
        diskFilesService.selectFolderNames(folderId, list);
        Collections.reverse(list); // 反转目录顺序
        return Result.success(list);
    }

    /**
     * 文件使用统计
     * @param days 统计天数范围（查询最近N天的文件操作记录）
     * @return {@link Result} 包含统计数据的结果对象（Dict格式的键值对集合）
     */
    @GetMapping("/count")
    public Result count(@RequestParam Integer days) {
        List<Dict> list = diskFilesService.count(days);
        return Result.success(list);
    }

    /**
     * 获取文件树形结构
     * @param request HTTP请求上下文（用于获取当前用户ID）
     * @return {@link Result} 包含树形结构的结果对象（前端可渲染为目录树）
     * @implNote 当前示例固定userId=1，实际应从session获取（示例代码已注释相关实现）
     */
    @GetMapping("/getFileTree")
    public Result<List<DiskFiles>> getFileTree(HttpServletRequest request) {
        // Account account = (Account) request.getSession().getAttribute("user");
        // Integer userId = account.getId();
        Integer userId = 1; // 示例固定值，实际应取消注释上方代码
        List<DiskFiles> tree = diskFilesService.getFileTree(userId);
        return Result.success(tree);
    }
}